﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Task.cs" company="BerlinSoft">
//   Wernfried Schwenkner
// </copyright>
// <summary>
//   Defines the Task type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Data.SqlServerCe;
using System.Diagnostics.CodeAnalysis;
using System.Drawing;
using System.Windows.Forms;
using SenseTimeTracker.Misc;
using StedySoft.SenseSDK;
using StedySoft.SenseSDK.DrawingCE;

namespace SenseTimeTracker.BusinessLayer
{
	/// <summary>
	/// Class implements the task
	/// </summary>
	public class Task : IColumnSortable
	{
		/// <summary>
		/// Task id column name
		/// </summary>
		public const string IdColumnName = "taskId";

		/// <summary>
		/// Client id column name
		/// </summary>
		public const string clientIdColumnName = "clientId";

		/// <summary>
		/// Project id column name
		/// </summary>
		public const string ProjectIdColumnName = "projectId";

		/// <summary>
		/// Category id column name
		/// </summary>
		public const string CategoryIdColumnName = "taskCategoryId";

		/// <summary>
		/// Person id column name
		/// </summary>
		public const string PersonIdColumnName = "personId";

		/// <summary>
		/// Name column name
		/// </summary>
		public const string NameColumnName = "taskName";

		/// <summary>
		/// Number column name
		/// </summary>
		public const string NumberColumnName = "taskNumber";

		/// <summary>
		/// Type column name
		/// </summary>
		public const string TypeColumnName = "taskType";

		/// <summary>
		/// Description column name
		/// </summary>
		public const string DescriptionColumnName = "taskDescription";

		/// <summary>
		/// Default description column name
		/// </summary>
		public const string DefaultDescriptionColumnName = "taskDefaultDescription";

		/// <summary>
		/// Location column name
		/// </summary>
		public const string LocationColumnName = "taskLocation";
		private const string completedColumnName = "taskCompleted";
		private const string lockCompletedColumnName = "taskLockCompleted";
		private const string terpExportLocationColumnName = "taskTerpExportLocation";
		private const string estimatedTimeColumnName = "taskEstimate";
		public const string ColorColumnName = "taskColor";
		public const string TableName = "Tasks";

		private Guid id = Guid.NewGuid();
		private Guid clientId = Persistance.Instance.FilterForTasks.ClientFilter;
		private Guid projectId = Persistance.Instance.FilterForTasks.ProjectFilter;
		private Guid categoryId = DatabaseManager.UnknownTaskCategoryId;
		private string name = string.Empty;
		private string number = string.Empty;
		private string type = string.Empty;
		private string description = string.Empty;
		private string defaultDescription = string.Empty;
		private string location = string.Empty;
		private bool completed = false;
		private bool lockCompleted = false;
		private bool terpExportLocation = false;
		private int estimatedTime = 0;
		private Color color = Color.Empty;

		public DateTime Date
		{
			get { return DateTime.MinValue; }
		}

		public TimeSpan Duration
		{
			get { return TimeSpan.Zero; }
		}

		public Guid Id
		{
			get { return id; }
			set { id = value; }
		}

		[SuppressMessage("Microsoft.StyleCop.CSharp.ReadabilityRules", "SA1107:CodeMustNotContainMultipleStatementsOnOneLine", Justification = "can contain serialize")]
		public Guid Client
		{
			get { return clientId; }
			set { clientId = value; Persistance.Instance.SelectedClient = value; }
		}

		[SuppressMessage("Microsoft.StyleCop.CSharp.ReadabilityRules", "SA1107:CodeMustNotContainMultipleStatementsOnOneLine", Justification = "can contain serialize")]
		public Guid Project
		{
			get { return projectId; }
			set { projectId = value; Persistance.Instance.SelectedProject = value; }
		}

		public string Name
		{
			get { return name; }
			set { name = value; }
		}

		public string Number
		{
			get { return number; }
			set { number = value; }
		}

		public string Type
		{
			get { return type; }
			set { type = value; }
		}

		public Guid Category
		{
			get { return categoryId; }
			set { categoryId = value; }
		}

		public string Description
		{
			get { return description; }
			set { description = value; }
		}

		public string DefaultDescription
		{
			get { return defaultDescription; }
			set { defaultDescription = value; }
		}

		public string Location
		{
			get { return location; }
			set { location = value; }
		}

		public bool Completed
		{
			get { return completed; }
			set { completed = value; }
		}

		public bool LockCompleted
		{
			get { return lockCompleted; }
			set { lockCompleted = value; }
		}

		public bool TerpExportLocation
		{
			get { return terpExportLocation; }
			set { terpExportLocation = value; }
		}

		public int EstimatedTime
		{
			get { return estimatedTime; }
			set { estimatedTime = value; }
		}

		public Color Color
		{
			get { return color; }
			set { color = value; }
		}

		public static List<Task> Tasks
		{
			get
			{
				List<Task> tasks = new List<Task>();
				SqlCeCommand command = new SqlCeCommand(
						"SELECT " +
						IdColumnName + ", " +
						"Projects." + clientIdColumnName + ", " +
						"Projects." + ProjectIdColumnName + ", " +
						CategoryIdColumnName + ", " +
						NameColumnName + ", " +
						NumberColumnName + ", " +
						TypeColumnName + ", " +
						DescriptionColumnName + ", " +
						DefaultDescriptionColumnName + ", " +
						LocationColumnName + ", " +
						completedColumnName + ", " +
						lockCompletedColumnName + ", " +
						terpExportLocationColumnName +
						" FROM " + TableName +
						" INNER JOIN Projects ON Tasks.projectId = Projects.ProjectId",
						DatabaseManager.DbConnection);
				bool shallOpen = DatabaseManager.DbConnection.State != System.Data.ConnectionState.Open;
				if (shallOpen)
				{
					DatabaseManager.DbConnection.Open();
				}

				SqlCeDataReader reader = command.ExecuteReader();
				while (reader.Read())
				{
					tasks.Add(new Task
					{
						Id = (Guid)reader[IdColumnName],
						Client = (Guid)reader[clientIdColumnName],
						Project = (Guid)reader[ProjectIdColumnName],
						Category = (Guid)reader[CategoryIdColumnName],
						Name = reader[NameColumnName].ToString(),
						Number = reader[NumberColumnName].ToString(),
						Type = reader[TypeColumnName].ToString(),
						Description = reader[DescriptionColumnName].ToString(),
						DefaultDescription = reader[DefaultDescriptionColumnName].ToString(),
						Location = reader[LocationColumnName].ToString(),
						Completed = (bool)reader[completedColumnName],
						LockCompleted = (bool)reader[lockCompletedColumnName],
						TerpExportLocation = (bool)reader[terpExportLocationColumnName],
					});
				}

				if (shallOpen)
				{
					DatabaseManager.DbConnection.Close();
				}

				return tasks;
			}
		}

		public static Task GetTask(Guid id)
		{
			Task task = null;
			SqlCeCommand command = new SqlCeCommand(
				"SELECT " +
				NumberColumnName + ", " +
				NameColumnName + ", " +
				TypeColumnName + ", " +
				completedColumnName + ", " +
				lockCompletedColumnName + ", " +
				estimatedTimeColumnName + ", " +
				DescriptionColumnName + ", " +
				DefaultDescriptionColumnName + ", " +
				"taskLocation, taskCategoryId, taskColor, taskTerpExportLocation, Tasks.projectId, clientId " +
				"FROM Tasks " +
				"INNER JOIN Projects ON Tasks.projectId = Projects.ProjectId " +
				"WHERE taskId=@taskId",
				DatabaseManager.DbConnection);
			command.Parameters.Add(IdColumnName, id);
			DatabaseManager.DbConnection.Open();
			SqlCeDataReader reader = command.ExecuteReader();

			if (reader.Read())
			{
				task = new Task
				{
					Id = id,
					Client = new Guid(reader[clientIdColumnName].ToString()),
					Project = new Guid(reader[ProjectIdColumnName].ToString()),
					Category = new Guid(reader[CategoryIdColumnName].ToString()),
					Name = reader[NameColumnName].ToString(),
					Number = reader[NumberColumnName].ToString(),
					Type = reader[TypeColumnName].ToString(),
					Description = reader[DescriptionColumnName].ToString(),
					DefaultDescription = reader[DefaultDescriptionColumnName].ToString(),
					Location = reader[LocationColumnName].ToString(),
					Completed = (bool)reader[completedColumnName],
					LockCompleted = (bool)reader[lockCompletedColumnName],
					TerpExportLocation = (bool)reader[terpExportLocationColumnName],
					EstimatedTime = (int)reader[estimatedTimeColumnName],
					Color = String.IsNullOrEmpty(reader[ColorColumnName].ToString()) ? Persistance.Instance.Colors.ActiveTasks.Color : Color.FromArgb(int.Parse(reader["taskColor"].ToString())),
				};

				DatabaseManager.DbConnection.Close();
			}

			return task;
		}

		public void Insert()
		{
			SqlCeCommand command = new SqlCeCommand(
				"INSERT INTO " + TableName + " " +
				"(taskId, projectId, personId, taskName, taskNumber, taskType, taskDescription, taskDefaultDescription, taskLocation, taskTerpExportLocation, taskEstimate, taskCompleted, taskLockCompleted, taskCategoryId, taskColor) " +
				"VALUES " +
				"(@taskId, @projectId, @personId, @taskName, @taskNumber, @taskType, @taskDescription, @taskDefaultDescription, @taskLocation, @taskTerpExportLocation, @taskEstimate, @taskCompleted, @taskLockCompleted, @taskCategoryId,  @taskColor)",
				DatabaseManager.DbConnection);
			command.Parameters.Add(IdColumnName, id);
			command.Parameters.Add(ProjectIdColumnName, projectId);
			command.Parameters.Add(PersonIdColumnName, Persistance.Instance.UserId);
			command.Parameters.Add(NameColumnName, name);
			command.Parameters.Add(NumberColumnName, number);
			command.Parameters.Add(TypeColumnName, type);
			command.Parameters.Add(DescriptionColumnName, description);
			command.Parameters.Add(DefaultDescriptionColumnName, defaultDescription);
			command.Parameters.Add(LocationColumnName, location);
			command.Parameters.Add(terpExportLocationColumnName, terpExportLocation);
			command.Parameters.Add(estimatedTimeColumnName, estimatedTime);
			command.Parameters.Add(completedColumnName, completed);
			command.Parameters.Add(lockCompletedColumnName, lockCompleted);
			command.Parameters.Add(CategoryIdColumnName, categoryId);
			command.Parameters.Add(ColorColumnName, color.ToArgb());
			DatabaseManager.DbConnection.Open();
			command.ExecuteNonQuery();
			DatabaseManager.DbConnection.Close();
		}

		public void Update()
		{
			SqlCeCommand command = new SqlCeCommand(
				"UPDATE " + TableName + " SET " +
				"projectId=@projectId, " +
				"taskName=@taskName, " +
				"taskNumber=@taskNumber, " +
				"taskType=@taskType, " +
				"taskDescription=@taskDescription, " +
				"taskDefaultDescription=@taskDefaultDescription, " +
				"taskLocation=@taskLocation, " +
				"taskTerpExportLocation=@taskTerpExportLocation, " +
				"taskEstimate=@TaskEstimate, " +
				"taskCompleted=@taskCompleted, " +
				"taskCategoryId=@taskCategoryId, " +
				"taskLockCompleted=@taskLockCompleted, " +
				"taskColor=@taskColor " +
				"WHERE taskId=@taskId",
				DatabaseManager.DbConnection);
			command.Parameters.Add(IdColumnName, id);
			command.Parameters.Add("@projectId", projectId);
			command.Parameters.Add("@taskName", name);
			command.Parameters.Add("@taskNumber", number);
			command.Parameters.Add("@taskType", type);
			command.Parameters.Add("@taskDescription", description);
			command.Parameters.Add("@taskDefaultDescription", defaultDescription);
			command.Parameters.Add("@taskLocation", location);
			command.Parameters.Add("@taskTerpExportLocation", terpExportLocation);
			command.Parameters.Add("@taskEstimate", estimatedTime);
			command.Parameters.Add("@taskCompleted", completed);
			command.Parameters.Add("@taskCategoryId", categoryId);
			command.Parameters.Add("@taskLockCompleted", lockCompleted);
			command.Parameters.Add("@taskColor", color.ToArgb());
			DatabaseManager.DbConnection.Open();
			command.ExecuteNonQuery();
			DatabaseManager.DbConnection.Close();
		}

		/// <summary>
		/// Delets a task
		/// </summary>
		/// <param name="taskId">Id of the task to be deleted</param>
		public static void Delete(Guid taskId)
		{
			SqlCeCommand command = new SqlCeCommand(
				"DELETE FROM Tasks " +
				"WHERE taskId = @taskId",
				DatabaseManager.DbConnection);
			command.Parameters.Add("@taskId", taskId);
			DatabaseManager.DbConnection.Open();
			try
			{
				command.ExecuteNonQuery();
			}
			catch
			{
				if (SenseAPIs.SenseMessageBox.Show("Remove all records\nfor this project also?", "Remove task", SenseMessageBoxButtons.YesNo) == DialogResult.Yes)
				{
					command.CommandText = "DELETE FROM " + TimeCard.TableName + " WHERE taskId = @taskId";
					command.ExecuteNonQuery();
					command.CommandText = "DELETE FROM Tasks WHERE taskId = @taskId";
					command.ExecuteNonQuery();
				}
			}

			DatabaseManager.DbConnection.Close();
		}
	}
}
